Tuples and Lists

Tuples

A Python Tuple is an immutable sequence of fixed sized. They are created using round brackets () with commas to separate the elements.


In [1]:
('x', 'y', 'z')


Out[1]:
('x', 'y', 'z')

The elements of a tuple need not have the same type.


In [2]:
(1, 'b', 2.5)


Out[2]:
(1, 'b', 2.5)

Extracting Elements from Tuples

Given a tuple it is possible to extract the elements from it in various ways. Note that Python uses 0-based indexing, meaning that the first element of a tuple is at position 0, the second element at position 1, and so on.


In [3]:
# Assigning a tuple to the variable tup
tup = ('first', 'second', 'third')

In [4]:
tup[0] # Extract the first element.


Out[4]:
'first'

In [5]:
tup[1] # Extract the second element.


Out[5]:
'second'

In [6]:
tup[2] # Extract the third element.


Out[6]:
'third'

In [7]:
tup[3] # Extracting a non-existent element.


---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-7-3446438f3359> in <module>()
----> 1 tup[3] # Extracting a non-existent element.

IndexError: tuple index out of range

Note that this last example results in an error from attempting to extract an element that doesn't exist. It is also possible to extract the elements of a tuple as follows.


In [8]:
a, b, c = tup
print(a)
print(b)
print(c)


first
second
third

The immutable aspect of tuples will be explained in a bit.

Lists

A Python List is a mutable sequence. Unlike tuples they don't have a fixed size. They are created using square brackets [] with commas to separate the elements.


In [9]:
["a", "b", "c"]


Out[9]:
['a', 'b', 'c']

Lists can be added together to create larger lists.


In [10]:
[1, 2] + [3, 4] + [5, 6]


Out[10]:
[1, 2, 3, 4, 5, 6]

Extracting Elements from Lists

Given a list it is possible to extract its elements in much the same way you would a tuple.


In [11]:
# Creating a list and assigning it to the variable x.
lis = [1, 2, 3, 4, 5]
lis


Out[11]:
[1, 2, 3, 4, 5]

In [12]:
lis[0] # Extract the first element.


Out[12]:
1

In [13]:
lis[1] # Extract the second element.


Out[13]:
2

In [14]:
lis[-1] # Extract the last element.


Out[14]:
5

In [15]:
lis[-2] # Extract the second to last element.


Out[15]:
4

List Slicing

It's also possible to slice out chunks of a list.


In [16]:
lis[:3] # Extract the first three elements or equivalently
        # extract elements up to (but not including) the fourth element.


Out[16]:
[1, 2, 3]

In [17]:
lis[3:] # Drop the first three elements and return the rest or equivalently
        # extract elements from the fourth element onwards.


Out[17]:
[4, 5]

In [18]:
lis[1:4] # Extract elements from the second element up to
         # (but not including the fifth).


Out[18]:
[2, 3, 4]

Mutability

Lists are mutable, so let's mutate (ie. change) them.


In [19]:
lis


Out[19]:
[1, 2, 3, 4, 5]

In [20]:
# Adding an element to the end of a list.
lis.append(6)
lis


Out[20]:
[1, 2, 3, 4, 5, 6]

In [21]:
# Adding a list to the end of a list.
lis.extend([7,8,9])
lis


Out[21]:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

In [22]:
# Removing an element from the end of a list.
element = lis.pop()
(element, lis)


Out[22]:
(9, [1, 2, 3, 4, 5, 6, 7, 8])

In [23]:
# Changing an element in a list.
lis[3] = 42
lis


Out[23]:
[1, 2, 3, 42, 5, 6, 7, 8]

Tuples and Mutability

Compare this behaviour to that of tuples.


In [24]:
tup[0] = 0


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-b3888d60d6d4> in <module>()
----> 1 tup[0] = 0

TypeError: 'tuple' object does not support item assignment

In [25]:
tup.append("fourth")


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-25-d760edb1b9d4> in <module>()
----> 1 tup.append("fourth")

AttributeError: 'tuple' object has no attribute 'append'

Trying to add or change an element in a tuple results in an error. Tuples cannot be changed after they are constructed, hence they are immutable unlike lists.

Useful List Functions

range

The range function can be used to generate lists of equidistantly spaced integers in various forms.


In [26]:
range(10)


Out[26]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [27]:
range(5, 15)


Out[27]:
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

In [28]:
range(4, 24, 2)


Out[28]:
[4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

zip

The zip function takes two or more lists and zips them together. This is easier to understand with an example.


In [29]:
x = ["a", "b", "c"]
y = [1  ,   2,   3]
zip(x, y)


Out[29]:
[('a', 1), ('b', 2), ('c', 3)]

Notice how the first elements of x and y are "zipped" together into a tuple in the new list, as are the second elements, and the third elements.


In [30]:
zip(x, y, ["Do", "Re", "Mi"])


Out[30]:
[('a', 1, 'Do'), ('b', 2, 'Re'), ('c', 3, 'Mi')]

enumerate

The enumerate functions generates a list of of pairs (two element tuples) in which the first element is the index/position of the element and the second element is the element in the original list.


In [31]:
x


Out[31]:
['a', 'b', 'c']

In [32]:
list(enumerate(x))


Out[32]:
[(0, 'a'), (1, 'b'), (2, 'c')]

Mutability Gotchas


In [33]:
lis


Out[33]:
[1, 2, 3, 42, 5, 6, 7, 8]

In [34]:
lis_copy = lis
lis_copy.append(9)
lis_copy


Out[34]:
[1, 2, 3, 42, 5, 6, 7, 8, 9]

As expected lis_copy now has 9 at the end of it.


In [35]:
lis


Out[35]:
[1, 2, 3, 42, 5, 6, 7, 8, 9]

However now lis also has 9 at the end of it. The line

lis_copy = lis

makes lis_copy point to the same underlying list as lis. What's needed here is a copy of the list. There are many ways of copying a list in Python, one of which follows.


In [36]:
lis_copy = lis[:]
lis_copy.pop()
print(lis)
print(lis_copy)


[1, 2, 3, 42, 5, 6, 7, 8, 9]
[1, 2, 3, 42, 5, 6, 7, 8]

Now the change in lis_copy does not affect lis.